package org.github.p2w.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.word.Word07Writer;
import cn.hutool.poi.word.WordUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.github.p2w.constant.Constant;
import org.github.p2w.entity.Config;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.awt.*;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;

/**
 * word
 *
 * @author xiayongchao
 * @date 2022/08/02
 */
public class Word {

    /**
     * 这里使用的是 hutool 的 Word07Writer
     */
    private final Word07Writer writer;

    public Word() {
        writer = WordUtil.getWriter();
    }

    /**
     * 创建标题
     *
     * @param title 标题
     */
    public void createTitle(String title) {
        writer.addText(ParagraphAlignment.CENTER, new Font("微软雅黑", Font.PLAIN, 16), title);
    }

    /**
     * 创建文本
     *
     * @param text   文本
     * @param rgbStr rgb颜色
     */
    public void createText(String text, String rgbStr) {
        createText(text, rgbStr, 0);
    }

    /**
     * 创建文本
     *
     * @param text     文本
     * @param rgbStr   rgb颜色
     * @param tabCount tab数
     */
    public void createText(String text, String rgbStr, int tabCount) {
        XWPFParagraph paragraph = writer.getDoc().createParagraph();
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run = paragraph.createRun();
        for (int i = 0; i < tabCount; i++) {
            run.addTab();
        }
        run.setText(text);
        Font font = new Font("微软雅黑", Font.PLAIN, 12);
        run.setFontFamily(font.getFamily());
        run.setFontSize(font.getSize());
        run.setBold(font.isBold());
        run.setItalic(font.isItalic());
        if (StrUtil.isNotBlank(rgbStr)) {
            run.setColor(rgbStr);
        }
    }

    /**
     * 创建空白行
     */
    public void createBreak() {
        writer.getDoc().createParagraph();
    }

    /**
     * 创建表
     * 创建表格
     *
     * @param data   表格数据
     * @param index  表格位置
     * @param rgbStr rgb颜色
     */
    public void createTable(Map<String, String> data, int index, String rgbStr) {
        XWPFDocument document = writer.getDoc();
        // 创建一个表格
        // 表格分两列，第一列为title，第二列为内容
        XWPFTable table = document.createTable(Constant.TABLE_TITLE.size(), 2);
        for (int i = 0; i < Constant.TABLE_TITLE.size(); i++) {
            XWPFTableRow row = table.getRow(i);
            String title = Constant.TABLE_TITLE.get(i);
            String value = data.get(title);
//            XWPFRun run0 = row.getCell(0).addParagraph().createRun();
//            run0.setColor(rgbStr);
//            XWPFRun run1 = row.getCell(1).addParagraph().createRun();
//            run1.setColor(rgbStr);
            row.getCell(0).setText(title);
            row.getCell(1).setText(value);
            if (Constant.TABLE_BREAK.contains(title)) {
                if (StrUtil.isNotBlank(value) && value.contains("\n")) {
                    // 需要将第二列的 \n => 换行
                    addBreakInCell(row.getCell(1));
                }
            }
        }
        setTableStyle(table, rgbStr);

        createBreak();
        document.createTable();
//        document.createTable(index, 3);
        document.setTable(index, table);
        createBreak();
    }

    /**
     * 匹配单元格内容，将 \n 替换为换行
     *
     * @param cell 单元
     */
    public void addBreakInCell(XWPFTableCell cell) {
        for (XWPFParagraph paragraph : cell.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                String[] lines = run.getText(0).split("\n");
                if (lines.length > 0) {
                    run.setText(lines[0], 0);
                    for (int i = 1; i < lines.length; i++) {
                        run.addBreak();
                        run.setText(lines[i]);
                    }
                }
            }
        }
    }

    /**
     * 设置表格样式
     *
     * @param table  表
     * @param borderRgbStr 边框rgb颜色
     */
    public void setTableStyle(XWPFTable table, String borderRgbStr) {
        CTTblPr tblPr = table.getCTTbl().getTblPr();
        CTTblBorders borders = tblPr.addNewTblBorders();
        STBorder.Enum tableBorderStyle = Constant.TABLE_BORDER_STYLE;
        String tableBorder = Config.getInstance().getTableBorder();
        if (StrUtil.isNotBlank(tableBorder)) {
            tableBorderStyle = STBorder.Enum.forString(tableBorder);
        }
        
        CTBorder hBorder = borders.addNewInsideH();
        hBorder.setVal(tableBorderStyle);
        hBorder.setSz(new BigInteger("1"));
        hBorder.setColor(borderRgbStr);

        CTBorder vBorder = borders.addNewInsideV();
        vBorder.setVal(tableBorderStyle);
        vBorder.setSz(new BigInteger("1"));
        vBorder.setColor(borderRgbStr);

        CTBorder lBorder = borders.addNewLeft();
        lBorder.setVal(tableBorderStyle);
        lBorder.setSz(new BigInteger("1"));
        lBorder.setColor(borderRgbStr);

        CTBorder rBorder = borders.addNewRight();
        rBorder.setVal(tableBorderStyle);
        rBorder.setSz(new BigInteger("1"));
        rBorder.setColor(borderRgbStr);

        CTBorder tBorder = borders.addNewTop();
        tBorder.setVal(tableBorderStyle);
        tBorder.setSz(new BigInteger("1"));
        tBorder.setColor(borderRgbStr);

        CTBorder bBorder = borders.addNewBottom();
        bBorder.setVal(tableBorderStyle);
        bBorder.setSz(new BigInteger("1"));
        bBorder.setColor(borderRgbStr);

        //设置表格中cell的长度不随着文字变化而变化
        CTTblLayoutType layoutType = tblPr.addNewTblLayout();
        layoutType.setType(STTblLayoutType.FIXED);

        //设置宽度
        CTTblWidth tblW = tblPr.getTblW();
        tblW.setW(new BigInteger(String.valueOf(Constant.TABLE_WIDTH)));
        tblW.setType(STTblWidth.DXA);

        //设置列宽度
        setColumnWidth(table);
    }

    /**
     * 设置列宽度
     *
     * @param table 表格
     */
    public void setColumnWidth(XWPFTable table) {
        List<XWPFTableRow> rows = table.getRows();
        rows.forEach(row -> {
            List<XWPFTableCell> cells = row.getTableCells();

            //设置宽度
            for (int i = 0; i < cells.size(); i++) {
                XWPFTableCell cell = cells.get(i);
                cell.getCTTc().addNewTcPr().addNewTcW().setW(new BigInteger(String.valueOf(Constant.TABLE_COLUMN_WIDTH[i])));
            }
        });
    }

    /**
     * 保存word
     *
     * @param file 文件路径
     */
    public void save(String file) {
        writer.flush(FileUtil.file(file));
        writer.close();
    }

}
